//创建时间 2022-3-23
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
static int DAYS_PER_MONTH[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

//日期类
class Date
{
public:
    /* 默认构造函数，以fullyear的形式给出年月日，默认值为1990年1月1日，同时设置日期分隔符为“-” */
    Date(int year = 1990, int month = 1, int day = 1)
    {
        this->year = year;
        this->month = month;
        this->day = day;
        separator = '-';
    }
    /* get、set方法 */
    // 设置日期，如果有非法的月或日，将其置为1
    void setDate(int year, int month, int day)
    {
        this->day = this->checkDay(day);
        this->month = month;
        this->year = year;
    }
    void setYear(int year)
    {
        this->year = year;
    }
    int getYear()
    {
        return year;
    }
    void setMonth(int month)
    {
        this->year = year;
    }
    int getMonth()
    {
        return month;
    }
    void setDay(int month)
    {
        this->day = day;
    }
    int getDay()
    {
        return day;
    }
    void setSeparator(char separator)
    {
        this->separator = separator;
    }

    /* 输出函数，请使用setfill(‘0’)和setw(2)。*/
    //以YYYY-MM-DD的形式打印，2011-01-08
    void printFullYear()
    {
        cout << year << separator << setfill('0') << setw(2) << month << separator << setfill('0') << setw(2) << day;
    }
    //以YY-MM-DD的形式打印，比如11-01-08
    void printStandardYear()
    {

        int temp = 0;
        int year = this->year;
        temp = year % 10;
        year /= 10;
        temp += year % 10 * 10;
        cout << setfill('0') << setw(2) << temp << separator << setfill('0') << setw(2) << month << separator << setfill('0') << setw(2) << day;
    }
    /* 计算当前日期与参数日期之间相差几个整年，仅考虑参数日期比当前日期晚的情况。注意参数为日期对象的引用。*/
    int fullYearsTo(Date &date)
    {
        if (date.month < this->month)
            date.year--;
        else if (date.month == this->month)
        {
            if (date.day < this->day)
                date.year--;
        }
        return date.year - this->year;
    }
    /* 计算当前日期与参数日期之间相差多少天(考虑闰年)，如果参数日期在当前日期之前，返回负数。注意参数为日期对象的引用。*/
    int daysTo(Date &date);
    /* 新增函数，可以被daysTo函数调用 */
    int getDayOfYear(int year, int month, int day);    //计算当前日期是本年的第几天
    int getLeftDaysYear(int year, int month, int day); //计算当前日期距本年结束还有几天，不包括当前日期这一天
private:
    int year;
    int month;
    int day;
    char separator; // 日期分隔符
    /* 新增数据成员和函数成员 */
    /*根据年和月，判断参数日期是否合法。如果合法，返回day，否则返回1。*/
    int checkDay(int day);
    bool isLeapyear(int year); //判断参数年是否是闰年。
    /*声明静态常变量，每月的天数，在.cpp文件中定义并初始化 */
};
//员工类
class Employee
{
public:
    //构造函数，使用“成员初始化器”初始化数据成员
    Employee(string first, string last, Date &hire, Date &birth) : firstName(first), lastName(last), birthDate(hire), hireDate(birth) {}
    //打印员工的信息。调用Date类的print函数，打印员工的生日和雇佣日期。
    void print()
    {
        cout << lastName << ", " << firstName << " Hired: ";
        hireDate.printFullYear();
        cout << " Birthday: ";
        birthDate.printFullYear();
    }
    //计算员工在参数指定的日期时，满多少岁。请使用Date类的fullYearsTo函数
    int getAge(Date &date)
    {
        int ages;
        ages = birthDate.fullYearsTo(date);
        return ages;
    }
    //计算该员工在参数指定的日期时，工作满了多少年。
    int getYearsWorked(Date &date)
    {
        int years;
        years = hireDate.fullYearsTo(date);
        return years;
    }
    //计算该员工在参数指定的日期时，工作了多少天。使用Date类的daysTo函数。
    int getDaysWorked(Date &date)
    {
        int days;
        days = hireDate.daysTo(date);
        return days;
    }

private:
    string firstName;
    string lastName;
    Date birthDate; //内嵌对象，出生日期
    Date hireDate;  //内嵌对象，雇用日期
};
//主函数
int main()
{
    Date birth(1969, 8, 11);
    Date hire(1998, 4, 1);
    Date today(2010, 4, 30);
    Employee manager("Bob", "Blue", birth, hire);
    cout << endl;
    manager.print();
    cout << endl;
    cout << manager.getAge(today) << endl;
    cout << manager.getDaysWorked(today) << endl;
    return 0;
}
//根据输入的年月判断day是否合法 不合法返回1 合法返回day
int Date::checkDay(int day)
{
    if (day < 1)
        day = 1;
    else if (month == 2)
    {
        if (isLeapyear(year))
        {
            DAYS_PER_MONTH[month - 1] = 29;
        }
    }
    if (day > DAYS_PER_MONTH[month - 1])
    {
        day = 1;
    }
    return day;
}
//判断是否为闰年
bool Date::isLeapyear(int year)
{
    bool flag;
    if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
    {
        flag = true;
    }
    else
        flag = false;
    return flag;
}
//计算参数日期与对象日期的间隔天数 如果为负值 返回负值
int Date::daysTo(Date &date)
{
    int gapDays = 0;
    if (date.year >= year)
    {
        for (int i = year; i < date.year; i++)
        {
            if (isLeapyear(i))
                gapDays++;
        }
        gapDays += 365 * (date.year - year);
        gapDays += getLeftDaysYear(year, month, day);
        gapDays += getDayOfYear(date.year, date.month, date.day);
    }
    else
    {
        for (int i = date.year; i < year; i++)
        {
            if (isLeapyear(i))
            {
                gapDays++;
            }
        }
        gapDays += 365 * (year - date.year);
        gapDays += getDayOfYear(year, month, day);
        gapDays += getLeftDaysYear(date.year, date.month, date.day);
        gapDays = -gapDays;
    }
    return gapDays;
}
//计算当前日期是本年的第几天
int Date::getDayOfYear(int year, int month, int day)
{
    int sum = 0;
    for (int i = 1; i < month; i++)
    {
        if (i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10)
            sum += 31;
        else if (i == 2)
        {
            if (isLeapyear(year))
                sum += 29;
            else
                sum += 28;
        }
        else
            sum += 30;
    }
    sum += day;
    return sum;
}
//计算当前日期距离本年结束还有多少天,不包括当前日期这一天
int Date::getLeftDaysYear(int year, int month, int day)
{
    int sum = 0;
    if (isLeapyear(year))

        sum = 366 - getDayOfYear(year, month, day);
    else
        sum = 365 - getDayOfYear(year, month, day);
    return sum;
}
